﻿#ifndef DIRECTORY_H
#define DIRECTORY_H
#include"XFileStruct.hpp"
#include<functional>
//目录结构
template<typename Ty>
class XDirectory:public XFileStruct<Ty>
{
public:
	XDirectory();
	XDirectory(const QString& name, XDirectory<Ty>* parent=nullptr);
	virtual~XDirectory()=default;
	//添加一个目录
	void addDir(const QString& name);
	//添加一个目录
	void addDir(XDirectory<Ty>* dir);
	//添加一个文件
	void addFile(const QString& name);
	//添加一个文件
	void addFile(XFileStruct<Ty>* file);
	//删除一个目录,是否释放它
	const bool removeDirectory(const QString& name,bool isDelete=true);
	//删除一个目录,是否释放它
	const bool removeDirectory(const XDirectory<Ty>* dir, bool isDelete = true);
	//返回子目录和文件
	const QList<XFileStruct<Ty>*>* childs()const;
	//返回数量
	size_t size()const;
	//返回是否是空目录
	bool isEmpty()const;
	//清空目录
	void clear()const;
	XDirectory<Ty>& operator<<(const XFileStruct<Ty>* file);
	XDirectory<Ty>& operator<<(const XDirectory<Ty>* dir);
private:
	//QString m_name;//名字
};

template<typename Ty>
inline XDirectory<Ty>::XDirectory()
	:XFileStruct<Ty>("")
{
	XFileStruct<Ty>::m_type = XFileType::dir;
}

template<typename Ty>
inline XDirectory<Ty>::XDirectory(const QString& name, XDirectory<Ty>* parent)
	:XFileStruct<Ty>(name, parent)
{
	XFileStruct<Ty>::m_type = XFileType::dir;
}

template<typename Ty>
inline void XDirectory<Ty>::addDir(const QString& name)
{
	XDirectory<Ty>* dir = new XDirectory<Ty>(name);
	XMultiWayTree<Ty>::addChild(dir);
}

template<typename Ty>
inline void XDirectory<Ty>::addDir(XDirectory<Ty>* dir)
{
	if(dir==nullptr)
		return ;
	XMultiWayTree<Ty>::addChild(dir);
}
template<typename Ty>
inline void XDirectory<Ty>::addFile(const QString& name)
{
	XFileStruct<Ty>* file = new XFileStruct<Ty>(name);
	XMultiWayTree<Ty>::addChild(file);
}
template<typename Ty>
inline void XDirectory<Ty>::addFile(XFileStruct<Ty>* file)
{
	if (file == nullptr)
		return ;
	XMultiWayTree<Ty>::addChild(file);
}
template<typename Ty>
inline bool XDirectory<Ty>::isEmpty()const
{
	return XMultiWayTree<Ty>::m_ChildList.empty();
}

template<typename Ty>
inline size_t XDirectory<Ty>::size()const
{
	return XMultiWayTree<Ty>::m_ChildList.size();
}

template<typename Ty>
inline const bool XDirectory<Ty>::removeDirectory(const QString& name, bool isDelete)
{
	auto& Chids = XMultiWayTree<Ty>::childs();
	auto ret=std::find_if(Chids.begin(), Chids.end(), [=](XDirectory<Ty>* dir) {return dir->name() = name; });
	if(ret== Chids.end())
		return false;
	Chids.erase(ret);
	if (isDelete)
	{
		(*ret)->clear();
		delete ret;
	}
	return true;
}

template<typename Ty>
inline const bool XDirectory<Ty>::removeDirectory(const XDirectory<Ty>* dir, bool isDelete)
{
	auto& Chids = XMultiWayTree<Ty>::childs();
	auto ret = std::find(Chids.begin(), Chids.end(), dir);
	if (ret == Chids.end())
		return false;
	Chids.erase(ret);
	if (isDelete)
	{
		(*ret)->clear();
		delete ret;
	}
	return true;
}
//
//template<typename Ty>
//inline void XDirectory<Ty>::setName(const QString& name)
//{
//	m_name = name;
//}
//
//template<typename Ty>
//const QString& XDirectory<Ty>::name() const
//{
//	return m_name;
//}
//
//template<typename Ty>
//inline void XDirectory<Ty>::setData(const Ty& data)
//{
//	XMultiWayTree<Ty>::setData(data,0);
//}
//
//template<typename Ty>
//const Ty& XDirectory<Ty>::data() const
//{
//	return XMultiWayTree<Ty>::data(0);
//}

template<typename Ty>
const QList<XFileStruct<Ty>*>* XDirectory<Ty>::childs() const
{
	return (QList<XFileStruct<Ty>*>*)(&XMultiWayTree<Ty>::childs());
}

template<typename Ty>
void XDirectory<Ty>::clear() const
{
	XMultiWayTree<Ty>::clearTree();
}
template<typename Ty>
inline XDirectory<Ty>& XDirectory<Ty>::operator<<(const XFileStruct<Ty>* file)
{
	addFile(file);
	return *this;
}
template<typename Ty>
inline XDirectory<Ty>& XDirectory<Ty>::operator<<(const XDirectory<Ty>* dir)
{
	addDir(dir);
	return *this;
}
#endif // !Directory_H
